<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>动态手势识别系统</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
        }

        body {
            background: linear-gradient(135deg, #1a2a6c, #b21f1f, #1a2a6c);
            background-size: 400% 400%;
            animation: gradientBG 15s ease infinite;
            color: #fff;
            min-height: 100vh;
            padding: 20px;
        }

        @keyframes gradientBG {
            0% { background-position: 0% 50%; }
            50% { background-position: 100% 50%; }
            100% { background-position: 0% 50%; }
        }

        .container {
            max-width: 1400px;
            margin: 0 auto;
        }

        header {
            text-align: center;
            padding: 20px 0;
            margin-bottom: 30px;
        }

        header h1 {
            font-size: 2.8rem;
            margin-bottom: 10px;
            text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
        }

        .main-content {
            display: flex;
            gap: 30px;
            margin-bottom: 30px;
            flex-wrap: wrap;
        }

        .video-container {
            flex: 3;
            min-width: 600px;
            background: rgba(0, 0, 0, 0.3);
            border-radius: 15px;
            overflow: hidden;
            box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
            position: relative;
        }

        #video-feed {
            width: 100%;
            height: 480px;
            display: block;
            background: #000;
        }

        .control-panel {
            display: flex;
            justify-content: center;
            gap: 20px;
            padding: 15px;
            background: rgba(0, 0, 0, 0.2);
            border-radius: 0 0 15px 15px;
        }

        .control-btn {
            padding: 12px 25px;
            border: none;
            border-radius: 50px;
            font-size: 1.1rem;
            font-weight: bold;
            cursor: pointer;
            transition: all 0.3s ease;
            display: flex;
            align-items: center;
            gap: 8px;
        }

        .control-btn.start {
            background: linear-gradient(135deg, #4caf50, #2e7d32);
            color: white;
            box-shadow: 0 4px 15px rgba(76, 175, 80, 0.3);
        }

        .control-btn.start:hover {
            transform: translateY(-3px);
            box-shadow: 0 6px 20px rgba(76, 175, 80, 0.4);
        }

        .control-btn.start:active {
            transform: translateY(1px);
        }

        .control-btn.stop {
            background: linear-gradient(135deg, #f44336, #c62828);
            color: white;
            box-shadow: 0 4px 15px rgba(244, 67, 54, 0.3);
        }

        .control-btn.stop:hover {
            transform: translateY(-3px);
            box-shadow: 0 6px 20px rgba(244, 67, 54, 0.4);
        }

        .control-btn.stop:active {
            transform: translateY(1px);
        }

        .control-btn:disabled {
            opacity: 0.6;
            cursor: not-allowed;
            transform: none !important;
            box-shadow: none !important;
        }

        .results-container {
            flex: 2;
            min-width: 300px;
            display: flex;
            flex-direction: column;
            gap: 25px;
        }

        .result-card {
            background: rgba(255, 255, 255, 0.1);
            backdrop-filter: blur(10px);
            border-radius: 15px;
            padding: 25px;
            box-shadow: 0 8px 20px rgba(0, 0, 0, 0.2);
        }

        .result-card h2 {
            font-size: 1.8rem;
            margin-bottom: 20px;
            color: #ffcc00;
            text-align: center;
        }

        .result-display {
            background: rgba(0, 0, 0, 0.3);
            border-radius: 10px;
            padding: 20px;
        }

        .result-item {
            display: flex;
            justify-content: space-between;
            margin-bottom: 15px;
            padding: 12px 15px;
            background: rgba(255, 255, 255, 0.05);
            border-radius: 8px;
            transition: all 0.3s ease;
        }

        .result-item:hover {
            background: rgba(255, 255, 255, 0.1);
            transform: translateY(-2px);
        }

        .result-label {
            font-weight: 600;
            font-size: 1.1rem;
        }

        .result-value {
            font-weight: 700;
            font-size: 1.2rem;
            color: #4caf50;
        }

        .result-value.active {
            color: #ff9800;
            animation: pulse 1.5s infinite;
        }

        @keyframes pulse {
            0% { opacity: 1; }
            50% { opacity: 0.7; }
            100% { opacity: 1; }
        }

        .instructions {
            background: rgba(255, 255, 255, 0.1);
            backdrop-filter: blur(10px);
            border-radius: 15px;
            padding: 25px;
            box-shadow: 0 8px 20px rgba(0, 0, 0, 0.2);
        }

        .instructions h2 {
            font-size: 1.8rem;
            margin-bottom: 20px;
            text-align: center;
            color: #00bcd4;
        }

        .gesture-grid {
            display: grid;
            grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
            gap: 15px;
            margin-top: 15px;
        }

        .gesture-item {
            background: rgba(255, 255, 255, 0.08);
            border-radius: 10px;
            padding: 15px;
            text-align: center;
            transition: all 0.3s ease;
            cursor: default;
        }

        .gesture-item:hover {
            background: rgba(255, 255, 255, 0.15);
            transform: translateY(-5px);
        }

        .gesture-icon {
            font-size: 2.5rem;
            margin-bottom: 8px;
        }

        .gesture-name {
            font-size: 0.95rem;
            opacity: 0.9;
        }

        footer {
            text-align: center;
            padding: 20px;
            font-size: 0.9rem;
            opacity: 0.7;
            margin-top: 20px;
        }

        .status-indicator {
            display: flex;
            align-items: center;
            justify-content: center;
            margin-top: 15px;
            gap: 10px;
        }

        .indicator-circle {
            width: 24px;
            height: 24px;
            border-radius: 50%;
            background: #555;
            transition: all 0.3s ease;
        }

        .active-recording {
            background: #ff9800;
            box-shadow: 0 0 10px #ff9800;
            animation: pulse 1s infinite;
        }

        .active-success {
            background: #4caf50;
            box-shadow: 0 0 10px #4caf50;
        }

        .active-error {
            background: #f44336;
            box-shadow: 0 0 10px #f44336;
            animation: pulse 0.5s infinite;
        }

        .progress-container {
            width: 100%;
            height: 6px;
            background: rgba(255, 255, 255, 0.1);
            border-radius: 3px;
            margin-top: 10px;
            overflow: hidden;
        }

        .progress-bar {
            height: 100%;
            background: linear-gradient(90deg, #ff9800, #ff5722);
            width: 0%;
            transition: width 0.5s ease;
        }

        .camera-status {
            position: absolute;
            top: 10px;
            left: 10px;
            background: rgba(0, 0, 0, 0.5);
            color: white;
            padding: 5px 10px;
            border-radius: 4px;
            font-size: 0.9rem;
        }

        .point-counter {
            position: absolute;
            bottom: 60px;
            right: 10px;
            background: rgba(0, 0, 0, 0.5);
            color: #ffcc00;
            padding: 5px 10px;
            border-radius: 4px;
            font-size: 0.9rem;
        }

        .recognition-card {
            background: rgba(0, 0, 0, 0.4);
            border-radius: 15px;
            padding: 20px;
            margin-top: 20px;
            display: none;
            box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
            border: 2px solid rgba(255, 255, 255, 0.1);
        }

        .recognition-card.active {
            display: block;
            animation: fadeIn 0.5s ease;
        }

        @keyframes fadeIn {
            from { opacity: 0; transform: translateY(10px); }
            to { opacity: 1; transform: translateY(0); }
        }

        .recognition-title {
            text-align: center;
            font-size: 1.5rem;
            margin-bottom: 15px;
            color: #ffcc00;
        }

        .recognition-result {
            display: flex;
            align-items: center;
            justify-content: center;
            gap: 15px;
            margin: 20px 0;
        }

        .recognition-icon {
            font-size: 3.5rem;
            animation: bounce 1s ease infinite;
        }

        @keyframes bounce {
            0%, 100% { transform: translateY(0); }
            50% { transform: translateY(-10px); }
        }

        .recognition-text {
            font-size: 2rem;
            font-weight: bold;
            color: #ff9800;
        }

        .recognition-confidence {
            text-align: center;
            font-size: 1.2rem;
            color: #4caf50;
        }

        .recognition-instruction {
            text-align: center;
            margin-top: 15px;
            color: #ccc;
            font-size: 0.9rem;
        }

        .recognition-card .progress-container {
            margin-top: 20px;
            height: 10px;
            border-radius: 5px;
        }

        .recognition-card .progress-bar {
            background: linear-gradient(90deg, #4caf50, #8bc34a);
        }

        .no-hand-overlay {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: rgba(0, 0, 0, 0.7);
            display: flex;
            align-items: center;
            justify-content: center;
            flex-direction: column;
            z-index: 10;
            opacity: 0;
            pointer-events: none;
            transition: opacity 0.5s ease;
        }

        .no-hand-overlay.active {
            opacity: 1;
            pointer-events: all;
        }

        .no-hand-icon {
            font-size: 5rem;
            margin-bottom: 20px;
            animation: pulse 2s infinite;
        }

        .no-hand-text {
            font-size: 2rem;
            text-align: center;
            max-width: 80%;
        }

        .recording-status {
            position: absolute;
            top: 10px;
            right: 10px;
            background: rgba(255, 87, 34, 0.8);
            color: white;
            padding: 5px 15px;
            border-radius: 20px;
            font-size: 0.9rem;
            display: flex;
            align-items: center;
            gap: 8px;
            animation: pulse 1.5s infinite;
        }

        .recording-dot {
            width: 12px;
            height: 12px;
            background: #ff0000;
            border-radius: 50%;
            animation: blink 1s infinite;
        }

        @keyframes blink {
            0%, 100% { opacity: 1; }
            50% { opacity: 0.3; }
        }

        @media (max-width: 1024px) {
            .main-content {
                flex-direction: column;
            }

            .video-container {
                max-width: 800px;
                margin: 0 auto;
            }
        }

        @media (max-width: 768px) {
            header h1 {
                font-size: 2.2rem;
            }

            .video-container {
                min-width: unset;
            }

            #video-feed {
                height: 360px;
            }

            .gesture-grid {
                grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
            }

            .recognition-result {
                flex-direction: column;
                gap: 10px;
            }

            .recognition-icon {
                font-size: 2.5rem;
            }

            .recognition-text {
                font-size: 1.5rem;
            }

            .no-hand-icon {
                font-size: 3rem;
            }

            .no-hand-text {
                font-size: 1.5rem;
            }

            .control-btn {
                padding: 10px 20px;
                font-size: 1rem;
            }
        }
    </style>
</head>
<body>
    <div class="container">
        <header>
            <h1>动态手势识别系统</h1>
            <p>在空中绘制形状，系统将识别您的动作</p>
        </header>

        <div class="main-content">
            <div class="video-container">
                <img src="{{ url_for('video_feed') }}" alt="实时摄像头画面" id="video-feed">
                <div class="camera-status" id="camera-status">摄像头正常</div>
                <div class="point-counter" id="point-counter">轨迹点: 0/25</div>
                <div class="recording-status" id="recording-status" style="display: none;">
                    <div class="recording-dot"></div>
                    轨迹录制中
                </div>

                <div class="no-hand-overlay" id="no-hand-overlay">
                    <div class="no-hand-icon">🖐️</div>
                    <div class="no-hand-text">未检测到手部，请将手置于摄像头前</div>
                </div>

                <div class="control-panel">
                    <button class="control-btn start" id="start-btn">
                        <svg width="20" height="20" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                            <path d="M8 5V19L19 12L8 5Z" fill="white"/>
                        </svg>
                        开始识别
                    </button>
                    <button class="control-btn stop" id="stop-btn" disabled>
                        <svg width="20" height="20" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                            <rect x="6" y="6" width="12" height="12" fill="white"/>
                        </svg>
                        停止识别
                    </button>
                </div>
            </div>

            <div class="results-container">
                <div class="result-card">
                    <h2>系统状态</h2>
                    <div class="result-display">
                        <div class="result-item">
                            <span class="result-label">追踪状态:</span>
                            <span id="tracking-status" class="result-value">未启动</span>
                        </div>
                        <div class="result-item">
                            <span class="result-label">轨迹点数:</span>
                            <span id="points-result" class="result-value">0/25</span>
                        </div>
                        <div class="result-item">
                            <span class="result-label">移动距离:</span>
                            <span id="distance-result" class="result-value">0px</span>
                        </div>
                        <div class="result-item">
                            <span class="result-label">上次识别:</span>
                            <span id="last-gesture" class="result-value">无</span>
                        </div>
                        <div class="status-indicator">
                            <div class="indicator-circle" id="motion-indicator"></div>
                            <span id="status-text">状态: 等待开始</span>
                        </div>
                    </div>
                </div>

                <div class="recognition-card" id="recognition-card">
                    <div class="recognition-title">识别结果</div>
                    <div class="recognition-result">
                        <div class="recognition-icon" id="recognition-icon">👋</div>
                        <div class="recognition-text" id="recognition-text">未识别</div>
                    </div>
                    <div class="recognition-confidence" id="recognition-confidence">置信度: 0%</div>
                    <div class="recognition-instruction">继续绘制下一个手势</div>
                    <div class="progress-container">
                        <div class="progress-bar" id="recognition-bar"></div>
                    </div>
                </div>

                <div class="instructions">
                    <h2>支持的手势</h2>
                    <div class="gesture-grid">
                        <div class="gesture-item">
                            <div class="gesture-icon">📐</div>
                            <div class="gesture-name">直角</div>
                        </div>
                        <div class="gesture-item">
                            <div class="gesture-icon">🔺</div>
                            <div class="gesture-name">锐角</div>
                        </div>
                        <div class="gesture-item">
                            <div class="gesture-icon">⚡</div>
                            <div class="gesture-name">闪电</div>
                        </div>
                        <div class="gesture-item">
                            <div class="gesture-icon">▲</div>
                            <div class="gesture-name">三角形</div>
                        </div>
                        <div class="gesture-item">
                            <div class="gesture-icon">H</div>
                            <div class="gesture-name">字母H</div>
                        </div>
                        <div class="gesture-item">
                            <div class="gesture-icon">R</div>
                            <div class="gesture-name">字母R</div>
                        </div>
                        <div class="gesture-item">
                            <div class="gesture-icon">W</div>
                            <div class="gesture-name">字母W</div>
                        </div>
                        <div class="gesture-item">
                            <div class="gesture-icon">Φ</div>
                            <div class="gesture-name">希腊字母Φ</div>
                        </div>
                        <div class="gesture-item">
                            <div class="gesture-icon">⭕</div>
                            <div class="gesture-name">圆圈</div>
                        </div>
                        <div class="gesture-item">
                            <div class="gesture-icon">🌊</div>
                            <div class="gesture-name">波浪</div>
                        </div>
                    </div>
                </div>
            </div>
        </div>

        <footer>
            <p>动态手势识别系统 © 2023 | 基于深度学习模型 | 版本 2.0</p>
        </footer>
    </div>

    <script>
        // 状态变量
        let trackingState = false; // false 表示未开始追踪，true 表示已开始追踪
        let lastValidGesture = null;
        let lastGestureTime = null;

        // 开始轨迹追踪
        function startTracking() {
            fetch('/start_tracking')
                .then(response => response.json())
                .then(data => {
                    if (data.status === 'success') {
                        trackingState = true;

                        // 更新UI
                        document.getElementById('tracking-status').textContent = '追踪中';
                        document.getElementById('tracking-status').classList.add('active');
                        document.getElementById('status-text').textContent = '状态: 追踪中';
                        document.getElementById('recording-status').style.display = 'flex';

                        // 更新按钮状态
                        document.getElementById('start-btn').disabled = true;
                        document.getElementById('stop-btn').disabled = false;
                    }
                })
                .catch(error => {
                    console.error('开始追踪错误:', error);
                });
        }

        // 停止轨迹追踪
        function stopTracking() {
            fetch('/stop_tracking')
                .then(response => response.json())
                .then(data => {
                    if (data.status === 'success') {
                        trackingState = false;

                        // 更新UI
                        document.getElementById('tracking-status').textContent = '已停止';
                        document.getElementById('tracking-status').classList.remove('active');
                        document.getElementById('status-text').textContent = '状态: 已停止';
                        document.getElementById('recording-status').style.display = 'none';

                        // 更新按钮状态
                        document.getElementById('start-btn').disabled = false;
                        document.getElementById('stop-btn').disabled = true;

                        // 获取最终识别结果
                        fetch('/get_results')
                            .then(response => response.json())
                            .then(data => {
                                if (data.motion === 'completed' && data.gesture &&
                                    data.gesture !== 'nohand' && data.gesture !== 'nomotion' &&
                                    data.gesture !== 'invalid' && data.gesture !== 'error') {
                                    lastValidGesture = data.gesture;
                                    lastGestureTime = new Date().getTime();

                                    // 显示识别结果
                                    showRecognitionResult(data);

                                    // 更新上次识别记录
                                    document.getElementById('last-gesture').textContent = lastValidGesture;
                                }
                            })
                            .catch(error => {
                                console.error('获取最终结果错误:', error);
                            });
                    }
                })
                .catch(error => {
                    console.error('停止追踪错误:', error);
                });
        }

        // 更新识别结果
        function updateResults() {
            fetch('/get_results')
                .then(response => response.json())
                .then(data => {
                    // 只在追踪状态下更新点数
                    if (trackingState) {
                        document.getElementById('points-result').textContent = `${data.trajectory_points || 0}/25`;
                        document.getElementById('point-counter').textContent = `轨迹点: ${data.trajectory_points || 0}/25`;
                    }

                    // 更新移动距离
                    const distance = data.distance || 0;
                    document.getElementById('distance-result').textContent = `${distance}px`;

                    // 处理手势识别
                    processGestureData(data);

                    // 更新状态指示器
                    updateStatusIndicator(data);

                    // 处理无手状态
                    handleNoHandState(data);
                })
                .catch(error => {
                    console.error('获取结果错误:', error);
                    document.getElementById('camera-status').textContent = "连接错误";
                    document.getElementById('camera-status').style.color = "#ff5555";
                });
        }

        // 处理手势数据
        function processGestureData(data) {
            // 只有在成功识别时才更新手势
            if (data.motion === 'completed' && data.gesture &&
                data.gesture !== 'nohand' && data.gesture !== 'nomotion' &&
                data.gesture !== 'invalid' && data.gesture !== 'error') {

                // 更新手势信息
                lastValidGesture = data.gesture;
                lastGestureTime = new Date().getTime();

                // 显示识别结果
                showRecognitionResult(data);

                // 更新上次识别记录
                document.getElementById('last-gesture').textContent = lastValidGesture;
            }
        }

        // 更新状态指示器
        function updateStatusIndicator(data) {
            const indicator = document.getElementById('motion-indicator');
            const statusText = document.getElementById('status-text');
            indicator.className = 'indicator-circle';

            // 如果不是追踪状态，不更新动作状态
            if (!trackingState) {
                return;
            }

            // 根据动作状态更新UI
            if (data.motion === 'moving') {
                indicator.classList.add('active-recording');
                statusText.textContent = "状态: 录制中...";
                document.getElementById('recognition-card').classList.remove('active');
            } else if (data.motion === 'completed') {
                indicator.classList.add('active-success');
                statusText.textContent = "状态: 识别成功!";
            } else if (data.motion === 'discarded') {
                indicator.classList.add('active-error');
                statusText.textContent = "状态: 轨迹无效";
                document.getElementById('recognition-card').classList.remove('active');
            } else if (data.motion === 'hand_lost') {
                indicator.classList.add('active-recording');
                statusText.textContent = "状态: 即将识别...";
                document.getElementById('recognition-card').classList.remove('active');
            } else {
                statusText.textContent = "状态: 等待手势";
            }
        }

        // 处理无手状态
        function handleNoHandState(data) {
            const noHandOverlay = document.getElementById('no-hand-overlay');
            const now = new Date().getTime();

            // 如果5秒内没有手势更新并且当前状态是nohand
            if (data.motion === 'nohand' &&
                (!lastGestureTime || (now - lastGestureTime) > 5000)) {

                // 显示无手提示
                noHandOverlay.classList.add('active');

                // 清除上次识别
                document.getElementById('last-gesture').textContent = "无";
            } else {
                // 隐藏无手提示
                noHandOverlay.classList.remove('active');
            }
        }

        // 显示识别结果
        function showRecognitionResult(data) {
            const recognitionCard = document.getElementById('recognition-card');
            const recognitionIcon = document.getElementById('recognition-icon');
            const recognitionText = document.getElementById('recognition-text');
            const recognitionConfidence = document.getElementById('recognition-confidence');
            const recognitionBar = document.getElementById('recognition-bar');

            // 只有在有有效识别时才显示卡片
            if (data.gesture && data.gesture !== 'nohand' && data.gesture !== 'nomotion' && data.gesture !== 'invalid') {
                recognitionCard.classList.add('active');

                // 设置识别结果
                recognitionText.textContent = data.gesture;

                // 设置置信度
                const confidence = data.confidence || 0;
                const confidencePercent = Math.round(confidence * 100);
                recognitionConfidence.textContent = `置信度: ${confidencePercent}%`;
                recognitionBar.style.width = `${confidencePercent}%`;

                // 根据手势类型设置图标
                const iconMap = {
                    'circle': '⭕',
                    'triangle': '▲',
                    'rectangle': '▭',
                    'star': '★',
                    'heart': '❤️',
                    'check': '✓',
                    'cross': '✗',
                    'arrow_up': '⬆️',
                    'arrow_down': '⬇️',
                    'infinity': '∞',
                    '直角': '📐',
                    '锐角': '🔺',
                    '闪电': '⚡',
                    '三角形': '▲',
                    '字母H': 'H',
                    '字母R': 'R',
                    '字母W': 'W',
                    '希腊字母Φ': 'Φ',
                    '圆圈': '⭕',
                    '波浪': '🌊'
                };

                recognitionIcon.textContent = iconMap[data.gesture] || '👋';
            } else {
                recognitionCard.classList.remove('active');
            }
        }

        // 初始化
        document.addEventListener('DOMContentLoaded', function() {
            // 绑定按钮事件
            document.getElementById('start-btn').addEventListener('click', startTracking);
            document.getElementById('stop-btn').addEventListener('click', stopTracking);

            // 每秒更新两次结果
            setInterval(updateResults, 500);

            // 初始状态更新
            updateResults();
        });

        // 使用空格键控制轨迹追踪
        document.addEventListener('keydown', function(event) {
            if (event.code === 'Space') {
                event.preventDefault(); // 阻止默认行为
                if (!trackingState) {
                    startTracking();
                } else {
                    stopTracking();
                }
            }
        });
    </script>
</body>
</html>